import socket

# TCP协议 实现客户端与服务端即时通讯案例。


# 1.创建一个服务端的socket，仅用于和客户端建立连接
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2.绑定IP
# bind方法参数是一个元组，里面内容是客户端的ip和端口。
# 如果ip位置写空字符串，表示任何客户端都可以来连接。
server_socket.bind(('', 8000))

# 3.服务端监听客户端消息
# listen(128) 表示，这个服务端最多可以接收 128个客户端的请求
server_socket.listen(128)

# 4.accept()接收客户端请求，得到一个与客户端交互的socket以及 请求该服务端的客户端IP和端口
# client_addr 是元组，第一个元素是客户端IP第二个元素是客户端端口
print('服务端开始阻塞')
socket2, client_addr = server_socket.accept()
# 这个方法会阻塞，调用accept()方法之后，服务端进入阻塞模式，等待客户端信息
while True:
    # print('服务端开始阻塞')
    # 5.接收客户端的信息,
    # recv(1024) 这个方法用于TCP传输协议的接收信息的方法，1024是每次传输数据为1024个字节，
    # decode('utf-8') 将接收的信息从字节格式转换为字符串格式。
    msg = socket2.recv(1024).decode('utf-8')

    # 如果客户端信息是exit终端聊天，退出循环，关闭socket
    if msg == 'exit':
        break

    # 打印来自客户端的信息
    print(f'来自客户端IP：{client_addr[0]}，端口：{client_addr[1]}的信息：{msg}')

    # 6.服务端发送信息给客户端进行交互
    # tcp传输协议中，发送数据交互用 send方法，send方法中传递参数只需要发送的信息，不需要填写客户端IP和端口地址信息。
    server_msg = input(f'服务端>>>').encode('utf-8')
    socket2.send(server_msg)

# 退出聊天，关闭服务端socket,顺序从里到外一次关闭socket
socket2.close()
server_socket.close()
